/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.rainbow.xml;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.rainbow.annotation.AnnotationUtils;
import org.rainbow.annotation.xml.NodeText;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 *
 * @author hironaga
 */
class NodeTextHandler extends XmlHandleComponent{

    private XmlCommonHandler commonHandler = XmlCommonHandler.getInstance();

    NodeTextHandler() {}

    void writeElement(Annotation annotation, Method getter, Field field, Object obj,
            Document doc, String xpath, int index, Node parentElement, XmlHandleHelper helper)
                                                            throws IOException {

        //Annotation Content
        NodeText nodeTextAnnt = (NodeText)annotation;
        String elementName = nodeTextAnnt.elementName();

        //String textValue;
        Object textValue;

        try{
            //Method:"getter" invoke: get-property
            textValue = getter.invoke(obj, new Object[0]);
        } catch (InvocationTargetException ex) {
            return;
        } catch (IllegalAccessException ex) {
            return;
        } catch (IllegalArgumentException ex) {
            return;
        } //try-catch

        //Add Text Node
        Node newElement = commonHandler.appendElement(doc, parentElement, elementName);
        String textValueStr = commonHandler.getStringVlaue(textValue);
        commonHandler.apendTextNode(doc, newElement, textValueStr);
        
    }

    void readElement(Annotation annotation, Method setter, Field field,
                                Object obj, Document doc, String xpath,
                                     Node parentElement, XmlHandleHelper helper)
                                                          throws IOException {

        //Annotation Content
        NodeText nodeTextAnnt = (NodeText)annotation;
        String elementName = nodeTextAnnt.elementName();

        Node firstChild = parentElement.getFirstChild();

        Class<?> filedType = field.getType();
        Class<?> fieldContentsType = null;
        List list = null;
        if(AnnotationUtils.isCollection(filedType)){
            fieldContentsType = (Class)AnnotationUtils.getCollectionContentType(field);
            String childXpath = xpath + "/" +elementName;
            NodeList nodeList = commonHandler.getNodeList(doc, childXpath);
            if(nodeList == null || nodeList.getLength() == 0){
                return;
            }
            //TODO
            list = new ArrayList();
            int nodeLength = nodeList.getLength();
            loop0: //loop:Node-List
            for(int idx0=0; idx0<nodeLength; idx0++){
                String elementTextValue =
                        commonHandler.getTextNodeValue(
                                commonHandler.getTextNode(
                                commonHandler.getElementNode(nodeList.item(idx0))));
                list.add(commonHandler.getPropertyValue(elementTextValue, fieldContentsType));
            }//loop0

            try{
                //Method:"setter" invoke: set-property
                setter.invoke(obj, new Object[]{ list } );
            } catch (IllegalArgumentException ex) {
            } catch (InvocationTargetException ex) {
            } finally{
                return;
            }//try-catch
        }

        loop3:
        while(firstChild != null ){
            Node elementNode = commonHandler.getElementNode(firstChild);
            if(elementNode == null){
                break loop3;
            }
            else{
                String firstChildNodeName = elementNode.getNodeName();
                //compare "Node-ElementName" "elementName@annotation"
                if( (firstChildNodeName != null) &&
                        (firstChildNodeName.equals(elementName)) ){
                    //Elmenet Text Value
                    String elementTextValue = commonHandler.getTextNodeValue(
                                        commonHandler.getTextNode(elementNode));

                try {
                        //Method:"setter" invoke: set-property
                        setter.invoke(obj, new Object[]{
                            commonHandler.getPropertyValue(elementTextValue, field.getType()) } );
                    } catch (IllegalArgumentException ex) {
                    } catch (InvocationTargetException ex) {
                    } finally{
                        return;
                    }//try-catch
                }//if
                firstChild = firstChild.getNextSibling();
            }//if
        }//loop3
    }

    void overwriteElement(Annotation annotation, Method getter,
            Field field, Object obj, Document doc, String xpath, int index,
            Node parentElement, XmlHandleHelper helper) throws IOException {

        //Annotation Content
        NodeText nodeTextAnnt = (NodeText)annotation;
        String elementName = nodeTextAnnt.elementName();

        //String textValue;
        Object textValue;

        try{
            //Method:"getter" invoke: get-property
            textValue = getter.invoke(obj, new Object[0]);
        } catch (InvocationTargetException ex) {
            return;
        } catch (IllegalAccessException ex) {
            return;
        } catch (IllegalArgumentException ex) {
            return;
        } //try-catch

        //Add Text Node
        Node currentElement = commonHandler.getLastElement(doc, xpath, elementName, index);
        String textValueStr = commonHandler.getStringVlaue(textValue);
        //TODO
        commonHandler.exchangeNodeTextValue(parentElement, textValueStr);
    }




}
